home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / archiver / lzhtv12.zip / LZHTV.PAS < prev    next >
Pascal/Delphi Source File  |  1990-04-22  |  14KB  |  600 lines

  1.  
  2. (*
  3.  * Copyright 1987, 1989 Samuel H. Smith;  All rights reserved
  4.  *
  5.  * Do not distribute modified versions without my permission.
  6.  * Do not remove or alter this notice or any other copyright notice.
  7.  * If you use this in your own program you must distribute source code.
  8.  * Do not use any of this in a commercial product.
  9.  *
  10.  *)
  11.  
  12. (*
  13.  * LzhTV - text view utility/door for LHARC-format .LZH files
  14.  *
  15.  *)
  16.  
  17. {$I prodef.inc}
  18. {$M 5000,0,0}  {minstack,minheap,maxheap}
  19. {$D+}          {Global debug information}
  20. {$L+}          {Local debug information}
  21.  
  22. program LzhTV;
  23.  
  24. Uses
  25.    Dos, DosMem, MiniCrt, Mdosio, Tools, CInput;
  26.  
  27. const
  28.    version = 'LzhTV:  LZH Text Viewer v1.2 of 04-22-90;  (C) 1990 S.H.Smith';
  29.  
  30.  
  31. (* ----------------------------------------------------------- *)
  32. (*
  33.  * file layout declarations
  34.  *
  35.  *)
  36.  
  37. type
  38.    lharc_header_rec = record
  39.       header_length:       byte;                {0=end of file}
  40.       header_check:        byte;                {checksum of remaining bytes}
  41.       compression_type:    array[1..5] of char; {'-lh0-'=store '-lh1-'=LZHuf}
  42.       compressed_size:     longint;
  43.       original_size:       longint;
  44.       file_time:           word;
  45.       file_date:           word;
  46.       file_attributes:     word;
  47.       file_name_length:    byte;
  48.       file_name:           string[65];
  49.       crc16:               word;
  50.    end;
  51.  
  52.  
  53. (* ----------------------------------------------------------- *)
  54. (*
  55.  * input file variables
  56.  *
  57.  *)
  58.  
  59. const
  60.    uinbufsize = 512;    {input buffer size}
  61. var
  62.    fileeof:       boolean;
  63.    infd:          dos_handle;
  64.    infn:          dos_filename;
  65.    inbuf:         array[1..uinbufsize] of byte;
  66.    inpos:         integer;
  67.    incnt:         integer;
  68.  
  69.    header:        lharc_header_rec;
  70.  
  71.  
  72. (* ----------------------------------------------------------- *)
  73. (*
  74.  * output stream variables
  75.  *
  76.  *)
  77.  
  78. const
  79.    obufsize = 4096;     (* output buffer size; should be 4096 *)
  80.    lookahead = 60;      (* lookahead buffer size *)
  81.    THRESHOLD = 2;
  82.    max_binary =   50;   {non-printing count before binary file trigger}
  83.    max_linelen =  200;  {line length before binary file triggered}
  84.  
  85.    maxlines: integer = 500;
  86.                         {maximum lines per session}
  87.  
  88. var
  89.    outbuf:        array[0..obufsize] of byte; {for rle look-back}
  90.    outpos:        longint;                 {absolute position in outfile}
  91.  
  92.    lson:    array[0..obufsize+1] of integer;
  93.    rson:    array[0..obufsize+257] of integer;
  94.    dad:     array[0..obufsize+1] of integer;
  95.  
  96.    uoutbuf:       string[max_linelen];    {disp line buffer}
  97.    binary_count:  integer;                {non-text chars so far}
  98.  
  99.  
  100. (* ----------------------------------------------------------- *)
  101. (*
  102.  * other working storage
  103.  *
  104.  *)
  105.  
  106. var
  107.    expand_files:        boolean;
  108.    header_present:      boolean;
  109.    default_pattern:     string20;
  110.    pattern:             string20;
  111.    action:              string20;
  112.  
  113.  
  114.  
  115. (* ----------------------------------------------------
  116.  *
  117.  *    file input/output handlers
  118.  *
  119.  *)
  120.  
  121. procedure skip_rest;
  122. begin
  123.    dos_lseek(infd,header.compressed_size-incnt,seek_cur);
  124.    fileeof := true;
  125.    header.compressed_size := 0;
  126.    incnt := 0;
  127. end;
  128.  
  129. procedure skip_csize;
  130. begin
  131.    incnt := 0;
  132.    skip_rest;
  133. end;
  134.  
  135. procedure ReadByte(var x: byte);
  136. begin
  137.    if incnt = 0 then
  138.    begin
  139.       if header.compressed_size = 0 then
  140.       begin
  141.          fileeof := true;
  142.          exit;
  143.       end;
  144.  
  145.       inpos := sizeof(inbuf);
  146.       if inpos > header.compressed_size then
  147.          inpos := header.compressed_size;
  148.       incnt := dos_read(infd,inbuf,inpos);
  149.  
  150.       inpos := 1;
  151.       dec(header.compressed_size,incnt);
  152.    end;
  153.  
  154.    x := inbuf[inpos];
  155.    inc(inpos);
  156.    dec(incnt);
  157. end;
  158.  
  159.  
  160. (* ------------------------------------------------------------- *)
  161. procedure OutByte (c: integer);
  162.    (* output each character from archive to screen *)
  163.  
  164.    procedure flushbuf;
  165.    begin
  166.       disp(uoutbuf);
  167.       uoutbuf := '';
  168.    end;
  169.  
  170.    procedure addchar;
  171.    begin
  172.       inc(uoutbuf[0]);
  173.       uoutbuf[length(uoutbuf)] := chr(c);
  174.    end;
  175.  
  176.    procedure not_text;
  177.    begin
  178.       newline;
  179.       displn('This is not a text file!');
  180.       skip_rest;
  181.    end;
  182.    
  183. begin
  184.    outbuf[outpos mod obufsize] := c;
  185.    inc(outpos);
  186.  
  187. (********
  188. if c = 13 then
  189. else if c = 10 then begin
  190. if nomore then skip_rest else newline;
  191. end else write(chr(c));
  192. exit;
  193. ********)
  194.  
  195.    case c of
  196.    10:  begin
  197.            if linenum < 1000 then
  198.            begin
  199.               flushbuf;
  200.               newline;
  201.  
  202.               dec(maxlines);
  203.               if (maxlines < 1) and (not dump_user) then
  204.               begin
  205.                   newline;
  206.                   displn('You''ve seen enough.  Please download this file if you want to see more.');
  207.                   dump_user := true;
  208.               end;
  209.            end;
  210.  
  211.            if nomore or dump_user then
  212.               skip_rest;
  213.         end;
  214.  
  215.    13: ;
  216.  
  217.    26: begin
  218.           flushbuf;
  219.           skip_rest;         {jump to nomore mode on ^z}
  220.        end;
  221.  
  222.    8,9,32..255:
  223.        begin
  224.           if length(uoutbuf) >= max_linelen then
  225.           begin
  226.              flushbuf;
  227.              if header.compressed_size > 10 then
  228.                 not_text;
  229.           end;
  230.  
  231.           if linenum < 1000 then   {stop display on nomore}
  232.              addchar;
  233.        end;
  234.  
  235.    else
  236.       begin
  237.          if binary_count < max_binary then
  238.             inc(binary_count)
  239.          else
  240.          if header.compressed_size > 10 then
  241.             not_text;
  242.       end;
  243.    end;
  244.  
  245. end;
  246.  
  247.  
  248. (* ---------------------------------------------------------- *)
  249.  
  250. {$i unlzh.inc}    {lzh expander}
  251.  
  252.  
  253. (* ---------------------------------------------------------- *)
  254. (*
  255.  * This procedure displays the text contents of a specified archive
  256.  * file.  The filename must be fully specified and verified.
  257.  *
  258.  *)
  259.  
  260. procedure viewfile;
  261. var
  262.    b: byte;
  263.  
  264. begin
  265.    newline;
  266.    {default_color;}
  267.    binary_count := 0;
  268.    getbuf := 0;
  269.    getlen := 0;
  270.    incnt := 0;
  271.    outpos := 0;
  272.    uoutbuf := '';
  273.    fileeof := false;
  274.  
  275.    if header.compression_type = '-lh0-' then
  276.       while (not fileeof) and (not dump_user) do
  277.       begin
  278.          ReadByte(b);
  279.          OutByte(b);
  280.       end
  281.    else
  282.  
  283.    if header.compression_type = '-lh1-' then
  284.       UnLZHuf
  285.    else
  286.  
  287.       displn('Unknown compression method.');
  288.  
  289.    if nomore=false then
  290.       newline;
  291.    linenum := 1;
  292. end;
  293.  
  294.  
  295. (* ---------------------------------------------------------- *)
  296. procedure _itoa(i: integer; var sp);
  297. var
  298.    s: array[1..2] of char absolute sp;
  299. begin
  300.    s[1] := chr( (i div 10) + ord('0'));
  301.    s[2] := chr( (i mod 10) + ord('0'));
  302. end;
  303.  
  304. function format_date(date: word): string8;
  305. const
  306.    s:       string8 = 'mm-dd-yy';
  307. begin
  308.    _itoa(((date shr 9) and 127)+80, s[7]);
  309.    _itoa( (date shr 5) and 15,  s[1]);
  310.    _itoa( (date      ) and 31,  s[4]);
  311.    format_date := s;
  312. end;
  313.  
  314. function format_time(time: word): string8;
  315. const
  316.    s:       string8 = 'hh:mm:ss';
  317. begin
  318.    _itoa( (time shr 11) and 31, s[1]);
  319.    _itoa( (time shr  5) and 63, s[4]);
  320.    _itoa( (time shl  1) and 63, s[7]);
  321.    format_time := s;
  322. end;
  323.  
  324.  
  325. (* ---------------------------------------------------------- *)
  326. procedure process_file_header;
  327. var
  328.    n:             word;
  329.    fpos:          longint;
  330.    filename:      dos_filename;
  331.  
  332. begin
  333.    dos_lseek(infd,0,seek_cur);
  334.    fpos := dos_tell;
  335.  
  336.    while (dump_user = false) do
  337.    begin
  338.       set_function(fun_arcview);
  339.  
  340.       dos_lseek(infd,fpos,seek_start);
  341.       n := dos_read(infd,header.header_check,sizeof(byte));
  342.       n := dos_read(infd,header.compression_type,sizeof(header.compression_type));
  343.       n := dos_read(infd,header.compressed_size,sizeof(longint));
  344.       n := dos_read(infd,header.original_size,sizeof(longint));
  345.       n := dos_read(infd,header.file_time,sizeof(word));
  346.       n := dos_read(infd,header.file_date,sizeof(word));
  347.       n := dos_read(infd,header.file_attributes,sizeof(word));
  348.       n := dos_read(infd,he